home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / Mark Pilgrim / MSG Demo 1.4 / source / Demo ƒ / debinhex dispatch.c next >
Encoding:
C/C++ Source or Header  |  1994-10-30  |  6.8 KB  |  275 lines  |  [TEXT/KAHL]

  1. /**********************************************************************\
  2.  
  3. File:        debinhex dispatch.c
  4.  
  5. Purpose:    This module handles the main dispatch routine for
  6.             deBinHexing.
  7.  
  8. This program is free software; you can redistribute it and/or modify
  9. it under the terms of the GNU General Public License as published by
  10. the Free Software Foundation; either version 2 of the License, or
  11. (at your option) any later version.
  12.  
  13. This program is distributed in the hope that it will be useful,
  14. but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16. GNU General Public License for more details.
  17.  
  18. You should have received a copy of the GNU General Public License
  19. along with this program in a file named "GNU General Public License".
  20. If not, write to the Free Software Foundation, 675 Mass Ave,
  21. Cambridge, MA 02139, USA.
  22.  
  23. \**********************************************************************/
  24.  
  25. #include "debinhex dispatch.h"
  26. #include "debinhex.h"
  27. #include "file management.h"
  28. #include "error.h"
  29. #include "progress.h"
  30. #include "util.h"
  31. #include "file interface.h"
  32. #include "program globals.h"
  33.  
  34. typedef struct
  35. {
  36.     long        fileType;
  37.     long        fileCreator;
  38.     short        finderFlags;
  39.     long        dataLen;
  40.     long        resLen;
  41.     short        checksum;
  42. } BinHexHeaderStruct;
  43.  
  44. #define MAX_HEADER_OFFSET    10240
  45.  
  46. int DeBinHexDispatch(void)
  47. {
  48.     int                resultCode;
  49.     
  50.     outputFS=inputFS;
  51.     OpenInputFile();
  52.     InitDeBinHex();
  53.     resultCode=GetBinHexHeader();
  54.     if (resultCode!=allsWell)
  55.         return resultCode;
  56.     resultCode=CreateTempFile();
  57.     if (resultCode!=allsWell)
  58.         return resultCode;
  59.     SetupTempFile();
  60.     resultCode=BinHexDecode();
  61.     EndDeBinHex();
  62.     FinalizeFiles(resultCode==allsWell);
  63.     return resultCode;
  64. }
  65.  
  66. int GetBinHexHeader(void)
  67. {
  68.     unsigned char        namelen;
  69.     unsigned char        Buffy[100];
  70.     unsigned char        *theText;
  71.     int                    resultCode;
  72.     BinHexHeaderStruct    header;
  73.     unsigned long        realLen;
  74.     unsigned char        oneChar;
  75.     int                    iter;
  76.     Boolean                notDoneYet;
  77.     int                    offset;
  78.     
  79.     theText=NewPtrClear(MAX_HEADER_OFFSET);
  80.     Mymemcpy((Ptr)Buffy, (Ptr)((long)(*GetString(BINHEX_HEADER_STRING))+1), 47);
  81.     iter=1;
  82.     notDoneYet=TRUE;
  83.     realLen=ReadInputFile(inputRefNum, theText, 10240L);
  84.     if (realLen<0)
  85.         return kBinHexErr;
  86.     offset=0;
  87.     do
  88.     {
  89.         oneChar=*((unsigned char*)((long)theText+(offset++)));
  90.         if (offset==MAX_HEADER_OFFSET)
  91.         {
  92.             DisposePtr(theText);
  93.             return kBinHexErr;
  94.         }
  95.         if (oneChar==Buffy[iter])
  96.         {
  97.             iter++;
  98.             notDoneYet=(iter<41);
  99.         }
  100.         else
  101.         {
  102.             iter=0;
  103.             if (oneChar==Buffy[iter])
  104.                 iter++;
  105.         }
  106.     }
  107.     while (notDoneYet);
  108.     
  109.     notDoneYet=TRUE;
  110.     do
  111.     {
  112.         oneChar=*((unsigned char*)((long)theText+(offset++)));
  113.         if (offset==MAX_HEADER_OFFSET)
  114.         {
  115.             DisposePtr(theText);
  116.             return kBinHexErr;
  117.         }
  118.         if ((oneChar==0x0a) || (oneChar==0x0d))
  119.             notDoneYet=FALSE;
  120.     }
  121.     while (notDoneYet);
  122.     
  123.     oneChar=*((unsigned char*)((long)theText+(offset++)));
  124. if (offset==MAX_HEADER_OFFSET)
  125.     {
  126.         DisposePtr(theText);
  127.         return kBinHexErr;
  128.     }
  129.     notDoneYet=((oneChar==0x09) || (oneChar==0x0a) || (oneChar==0x0d) ||
  130.         (oneChar==0x20));
  131.  
  132.     while (notDoneYet)
  133.     {
  134.         oneChar=*((unsigned char*)((long)theText+(offset++)));
  135.         if (offset==MAX_HEADER_OFFSET)
  136.         {
  137.             DisposePtr(theText);
  138.             return kBinHexErr;
  139.         }
  140.         notDoneYet=((oneChar==0x09) || (oneChar==0x0a) || (oneChar==0x0d) ||
  141.             (oneChar==0x20));
  142.     }
  143.     
  144.     DisposePtr(theText);
  145.     
  146.     if (oneChar!=':')
  147.         return kBinHexErr;
  148.     
  149.     SetFPos(inputRefNum, 1, offset);
  150.     resultCode=GetNBytes(inputRefNum, (Ptr)Buffy, 1);
  151.     if (resultCode!=allsWell)
  152.         return resultCode;
  153.     namelen=Buffy[0];
  154.     resultCode=GetNBytes(inputRefNum, (Ptr)((long)Buffy+1), namelen+21);
  155.     if (resultCode!=allsWell)
  156.         return resultCode;
  157.     Mymemcpy((Ptr)(&header), (Ptr)((long)Buffy+namelen+2), sizeof(header));
  158.     *((char*)((long)Buffy+namelen+20))=0x00;
  159.     *((char*)((long)Buffy+namelen+21))=0x00;
  160.     if (header.checksum!=BinHexChecksum((Ptr)Buffy, namelen+22, TRUE))
  161.         return kBinHexErr;
  162.     Mymemcpy(outputFS.name, Buffy, namelen+1);
  163.     outputDFeof=header.dataLen;
  164.     outputRFeof=header.resLen;
  165.     theFileType=header.fileType;
  166.     theFileCreator=header.fileCreator;
  167.     theFileFlags=header.finderFlags;
  168.     
  169.     return allsWell;
  170. }
  171.  
  172. int BinHexDecode(void)
  173. {
  174.     Ptr                outputBuffer;
  175.     int                resultCode;
  176.     unsigned long    bufferLen;
  177.     Boolean            notDoneYet;
  178.     unsigned long    curPos, len, forkPos;
  179.     Boolean            useDF;
  180.     DialogPtr        theDlog;
  181.     unsigned int    oldcheck;
  182.     unsigned char    temp1,temp2;
  183.     
  184.     theDlog=OpenProgressDialog(outputDFeof+outputRFeof+4, "\pDeBinHex");
  185.     SetProgressText("\pConverting ",inputFS.name, "\p from BinHex format...","\p");
  186.     if (theDlog==0L)
  187.         Debugger();
  188.     DealWithOtherPeople();
  189.     bufferLen=BINHEX_BUFFER_LENGTH;
  190.     outputBuffer=NewPtr(bufferLen);
  191.     if (outputBuffer==0L)
  192.         return kNoMemory;
  193.     curPos=0L;
  194.     forkPos=0L;
  195.     notDoneYet=TRUE;
  196.     useDF=TRUE;
  197.     resultCode=allsWell;
  198.     BinHexChecksum(outputBuffer, 0, TRUE);
  199.     
  200.     do
  201.     {
  202.         if (useDF)
  203.             len=(outputDFeof+2-forkPos<bufferLen) ?
  204.                 outputDFeof+2-forkPos : bufferLen;
  205.         else
  206.             len=(outputRFeof+2-forkPos<bufferLen) ?
  207.                 outputRFeof+2-forkPos : bufferLen;
  208.         
  209.         resultCode=GetNBytes(inputRefNum, outputBuffer, len);
  210.  
  211.         if (resultCode==allsWell)
  212.         {
  213.             if (len!=bufferLen)
  214.             {
  215.                 if (useDF)
  216.                 {
  217.                     temp1=*((unsigned char*)((long)outputBuffer+outputDFeof-forkPos));
  218.                     temp2=*((unsigned char*)((long)outputBuffer+outputDFeof-forkPos+1));
  219.                     oldcheck=0;
  220.                     oldcheck+=temp1;
  221.                     oldcheck<<=8;
  222.                     oldcheck+=temp2;
  223.                     *((unsigned char*)((long)outputBuffer+outputDFeof-forkPos))=0x00;
  224.                     *((unsigned char*)((long)outputBuffer+outputDFeof-forkPos+1))=0x00;
  225.                     if (oldcheck!=BinHexChecksum(outputBuffer, len, FALSE))
  226.                         resultCode=kBinHexErr;
  227.                     if ((resultCode==allsWell) && (len>2))
  228.                         resultCode=WriteTempFile(outputDFRefNum, outputBuffer, len-2);
  229.                     useDF=FALSE;
  230.                     forkPos=0L;
  231.                     BinHexChecksum(outputBuffer, 0, TRUE);
  232.                 }
  233.                 else
  234.                 {
  235.                     temp1=*((unsigned char*)((long)outputBuffer+outputRFeof-forkPos));
  236.                     temp2=*((unsigned char*)((long)outputBuffer+outputRFeof-forkPos+1));
  237.                     oldcheck=0;
  238.                     oldcheck+=temp1;
  239.                     oldcheck<<=8;
  240.                     oldcheck+=temp2;
  241.                     *((unsigned char*)((long)outputBuffer+outputRFeof-forkPos))=0x00;
  242.                     *((unsigned char*)((long)outputBuffer+outputRFeof-forkPos+1))=0x00;
  243.                     if (oldcheck!=BinHexChecksum(outputBuffer, len, FALSE))
  244.                         resultCode=kBinHexErr;
  245.                     if ((resultCode==allsWell) && (len>2))
  246.                         resultCode=WriteTempFile(outputRFRefNum, outputBuffer, len-2);
  247.                     notDoneYet=FALSE;
  248.                 }
  249.             }
  250.             else
  251.             {
  252.                 forkPos+=len;
  253.                 BinHexChecksum(outputBuffer, len, FALSE);
  254.                 if (useDF)
  255.                     resultCode=WriteTempFile(outputDFRefNum, outputBuffer, len);
  256.                 else
  257.                     resultCode=WriteTempFile(outputRFRefNum, outputBuffer, len);
  258.             }
  259.             if (resultCode==allsWell)
  260.             {
  261.                 curPos+=len;
  262.                 UpdateProgressDialog(curPos);
  263.                 if (!DealWithOtherPeople())
  264.                     resultCode=userCancelErr;
  265.             }
  266.         }
  267.     }
  268.     while ((notDoneYet) && (resultCode==allsWell));
  269.  
  270.     DisposePtr(outputBuffer);
  271.     DismissProgressDialog();
  272.     
  273.     return resultCode;
  274. }
  275.